#ifndef GUDB_SERVER_H
#define GUDB_SERVER_H

#include "../protocol/gu_protocol.h"
#include "../../include/gudb.h"
#include <pthread.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>

// Server Configuration
typedef struct {
    char host[256];
    int port;
    char data_dir[512];
    char username[GU_MAX_USERNAME_SIZE];
    char password[GU_MAX_PASSWORD_SIZE];
    int max_connections;
    int worker_threads;
    bool daemon_mode;
    bool verbose;
} gudb_server_config_t;

// Client Session
typedef struct gudb_session {
    int sockfd;
    struct sockaddr_in client_addr;
    uint32_t session_id;
    bool authenticated;
    char username[GU_MAX_USERNAME_SIZE];
    char database[GU_MAX_DATABASE_SIZE];
    bool database_explicitly_selected;  // Whether user explicitly selected database with USE
    gudb_txn* current_txn;
    bool in_transaction;
    
    // Statistics
    uint64_t queries_executed;
    time_t connect_time;
    time_t last_activity;
    
    // Linked list
    struct gudb_session* next;
    struct gudb_session* prev;
} gudb_session_t;

// GuDB Server
typedef struct {
    gudb_server_config_t config;
    gudb* database;
    
    // Network
    int listen_sockfd;
    struct sockaddr_in server_addr;
    bool running;
    
    // Session management
    gudb_session_t* sessions;
    uint32_t session_count;
    uint32_t next_session_id;
    pthread_mutex_t session_mutex;
    
    // Thread pool
    pthread_t* worker_threads;
    pthread_t accept_thread;
    pthread_mutex_t work_mutex;
    pthread_cond_t work_cond;
    
    // Statistics
    uint64_t total_connections;
    uint64_t current_connections;
    uint64_t total_queries;
    time_t start_time;
    
    pthread_mutex_t stats_mutex;
} gudb_server_t;

// Server Functions

// Server lifecycle
gudb_server_t* gudb_server_create(void);
void gudb_server_destroy(gudb_server_t* server);
int gudb_server_init(gudb_server_t* server, gudb_server_config_t* config);
int gudb_native_server_start(gudb_server_t* server);
int gudb_native_server_stop(gudb_server_t* server);

// Configuration
int gudb_server_load_config(gudb_server_config_t* config, const char* config_file);
void gudb_server_init_default_config(gudb_server_config_t* config);
int gudb_server_parse_args(gudb_server_config_t* config, int argc, char* argv[]);
void gudb_server_print_usage(const char* program_name);

// Session management
gudb_session_t* gudb_session_create(int sockfd, struct sockaddr_in* client_addr, uint32_t session_id);
void gudb_session_destroy(gudb_session_t* session);
int gudb_server_add_session(gudb_server_t* server, gudb_session_t* session);
int gudb_server_remove_session(gudb_server_t* server, gudb_session_t* session);

// Protocol handling
int gudb_server_handle_connect(gudb_server_t* server, gudb_session_t* session, gu_packet_t* packet);
int gudb_server_handle_exec(gudb_server_t* server, gudb_session_t* session, gu_packet_t* packet);
int gudb_server_handle_query(gudb_server_t* server, gudb_session_t* session, gu_packet_t* packet);
int gudb_server_handle_ping(gudb_server_t* server, gudb_session_t* session, gu_packet_t* packet);
int gudb_server_handle_quit(gudb_server_t* server, gudb_session_t* session, gu_packet_t* packet);

// Response helpers
int gudb_server_send_auth_ok(gudb_session_t* session);
int gudb_server_send_auth_fail(gudb_session_t* session, const char* message);
int gudb_server_send_ok(gudb_session_t* session, const char* message);
int gudb_server_send_error(gudb_session_t* session, const char* message);
int gudb_server_send_result(gudb_session_t* session, result_t* gudb_result);
int gudb_server_send_pong(gudb_session_t* session);

// Threading
void* gudb_server_accept_thread(void* arg);
void* gudb_server_worker_thread(void* arg);
void* gudb_session_handler(void* arg);

// Utilities
void gudb_server_print_stats(gudb_server_t* server);
void gudb_server_log(gudb_server_t* server, const char* format, ...);
const char* gudb_session_get_client_ip(gudb_session_t* session);

// Authentication
int gudb_server_authenticate(gudb_server_t* server, const char* username, const char* password);

#endif // GUDB_SERVER_H